package gy.com.sansharescuesystem.adapter;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.map.TextureMapView;
import com.baidu.mapapi.model.LatLng;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

import java.util.ArrayList;
import java.util.List;

import gy.com.sansharescuesystem.R;
import gy.com.sansharescuesystem.callback.AcyncCallBack;
import gy.com.sansharescuesystem.entity.HistoryOrbit;
import gy.com.sansharescuesystem.entity.HistoryOrbitData;
import gy.com.sansharescuesystem.entity.RescueListResData;
import gy.com.sansharescuesystem.modle.QueryModel;
import gy.com.sansharescuesystem.modle.impl.QueryModelImpl;
import gy.com.sansharescuesystem.utils.Constant;
import gy.com.sansharescuesystem.utils.DateUtil;
import gy.com.sansharescuesystem.utils.MapUtil;
import gy.com.sansharescuesystem.utils.UIUtils;

/**
 * Created by 陈秋霖 on 2017-07-22.
 */

public class HistoryAdapter extends BaseAdapter {
    private Context context;
    private List<RescueListResData> datas;
    private LayoutInflater inflater;
    private List<LatLng> sosLoc = new ArrayList<>();
    private List<LatLng> actLoc = new ArrayList<>();
    private int mCurrentItem = -1;
    private PullToRefreshListView mListView;
    private BaiduMap mBaiduMap;
    private TextureMapView mMapView;
    private QueryModel model = new QueryModelImpl();
    private String mQuerySn;
    private String mShipId;
    private boolean ifFirst = true;
    private boolean shipOrbitGet = false;
    private boolean SOSOrbitGet = false;

    private static final int GET_SOS_ORBIT_SUCCESS = 1;
    private static final int GET_SOS_ORBIT_FAILE = 2;
    private static final int GET_SHIP_ORBIT_SUCCESS = 3;
    private static final int GET_SHIP_ORBIT_FAILE = 4;
    //广播
    private HistoryBroadcastReceiver historyBroadcastReceiver;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case GET_SOS_ORBIT_SUCCESS:
                    HistoryOrbit historyOrbit = (HistoryOrbit) msg.obj;
                    List<HistoryOrbitData> mOrbitData = historyOrbit.getData();
                    if (mOrbitData != null) {
                        sosLoc.clear();
                        for (int i = 0; i < mOrbitData.size(); i++) {
                            LatLng point = new LatLng(Double.parseDouble(mOrbitData.get(i).getLat())
                                    , Double.parseDouble(mOrbitData.get(i).getLog()));
                            sosLoc.add(point);
                        }
                    } else {
                        UIUtils.showToast(context, "无求救人员轨迹数据");
                    }
                    SOSOrbitGet = true;
                    drawAllMapMarkers();
                    break;
                case GET_SOS_ORBIT_FAILE:
                    UIUtils.showToast(context, "通过sn获取信息失败");
                    break;
                case GET_SHIP_ORBIT_SUCCESS:
                    HistoryOrbit historyShipOrbit = (HistoryOrbit) msg.obj;
                    List<HistoryOrbitData> mShipOrbitData = historyShipOrbit.getData();
                    if (mShipOrbitData != null) {
                        actLoc.clear();
                        for (int i = 0; i < mShipOrbitData.size(); i++) {
                            LatLng point = new LatLng(Double.parseDouble(mShipOrbitData.get(i).getLat())
                                    , Double.parseDouble(mShipOrbitData.get(i).getLog()));
                            actLoc.add(point);
                        }
                    } else {
                        UIUtils.showToast(context, "无救援船只轨迹数据");
                    }
                    shipOrbitGet = true;
                    drawAllMapMarkers();
                    break;
                case GET_SHIP_ORBIT_FAILE:
                    UIUtils.showToast(context, "通过ship获取信息失败");
                    break;
            }
        }
    };

    private void drawAllMapMarkers() {
        if (SOSOrbitGet && shipOrbitGet) {
            if (sosLoc.size() > 0 && actLoc.size() > 0) {
                //将地图定位到两点的连线中心位置
                moveToMapCenter();

            } else {
                if (sosLoc.size() > 0) {
                    moveToPoint(sosLoc);
                } else if (actLoc.size() > 0) {
                    moveToPoint(actLoc);
                }
            }
            //标记所有的记录点
            addTargets();
        }
    }

    private void moveToPoint(List<LatLng> list) {
        LatLng first = list.get(0);
        LatLng last = list.get(list.size() - 1);
        double distanse = MapUtil.getDistance(first.latitude, first.longitude, last.latitude, last.longitude);
        Log.i("info", "first = " + first + ",last = " + last + ",distance = " + distanse);
        float zoom = MapUtil.getZoom(distanse);
        if (ifFirst) {
            ifFirst = false;
            LatLng ll = new LatLng((first.latitude + last.latitude) / 2, (first.longitude + last.longitude) / 2);
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(ll).zoom(zoom);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }
    }

    private void moveToMapCenter() {
        LatLng sosStartPoint = new LatLng(sosLoc.get(0).latitude, sosLoc.get(0).longitude);
        LatLng sosEndPoint = new LatLng(sosLoc.get(sosLoc.size() - 1).latitude, sosLoc.get(sosLoc.size() - 1).longitude);
        LatLng shipStartPoint = new LatLng(actLoc.get(0).latitude, actLoc.get(0).longitude);
        LatLng shipEndPoint = new LatLng(actLoc.get(actLoc.size() - 1).latitude, actLoc.get(actLoc.size() - 1).longitude);
        double distanceFirst = MapUtil.getDistance(sosStartPoint.latitude, sosStartPoint.longitude, shipStartPoint.latitude, shipStartPoint.longitude);
        double distanceEnd = MapUtil.getDistance(sosEndPoint.latitude, sosEndPoint.longitude, shipEndPoint.latitude, shipEndPoint.longitude);
        LatLng ll = null;
        float zoom = 0;
        if (distanceEnd > distanceFirst) {
            zoom = MapUtil.getZoom(distanceEnd);
            ll = new LatLng((sosEndPoint.latitude + shipEndPoint.latitude) / 2
                    , (sosEndPoint.longitude + shipEndPoint.longitude) / 2);
        } else {
            zoom = MapUtil.getZoom(distanceFirst);
            ll = new LatLng((sosStartPoint.latitude + shipStartPoint.latitude) / 2
                    , (sosStartPoint.longitude + shipStartPoint.longitude) / 2);
        }
        if (ifFirst) {
            ifFirst = false;
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(ll).zoom(zoom);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }
    }

    public HistoryAdapter(Context context, List<RescueListResData> datas, PullToRefreshListView listView) {
        this.context = context;
        this.datas = datas;
        inflater = LayoutInflater.from(context);
        mListView = listView;
        historyBroadcastReceiver = new HistoryBroadcastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(Constant.RESCUE_DESTROY);
        filter.addAction(Constant.RESCUE_PAUSE);
        filter.addAction(Constant.RESCUE_RESUME);
        filter.addAction(Constant.RESCUE_STOP);
        filter.addAction(Constant.TO_COUNT_PAGE);
        filter.addAction(Constant.TO_HISTORY_PAGE);
        filter.addAction(Constant.TO_RESCUE_PAGE);
        context.registerReceiver(historyBroadcastReceiver, filter);
    }

    @Override
    public int getCount() {
        return datas.size();
    }

    @Override
    public Object getItem(int position) {
        return datas.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            SDKInitializer.initialize(context.getApplicationContext());
            convertView = inflater.inflate(R.layout.layout_history_item, null);
            holder = new ViewHolder();
            holder.showArea = (LinearLayout) convertView.findViewById(R.id.ll_history_show_area);
            holder.hideArea = (RelativeLayout) convertView.findViewById(R.id.rl_history_hide_area);
            holder.no = (TextView) convertView.findViewById(R.id.tv_history_no);
            holder.callNum = (TextView) convertView.findViewById(R.id.tv_history_call_num);
            holder.status = (ImageView) convertView.findViewById(R.id.iv_history_rescue_progress);
            holder.fallTime = (TextView) convertView.findViewById(R.id.tv_history_fall_time);
            holder.startTime = (TextView) convertView.findViewById(R.id.tv_history_chujing_time);
            holder.callTimes = (TextView) convertView.findViewById(R.id.tv_history_call_times);
            holder.machineNum = (TextView) convertView.findViewById(R.id.tv_history_machine_no);
            holder.goBack = (ImageButton) convertView.findViewById(R.id.iv_history_scroll_back);
            holder.mMap = (TextureMapView) convertView.findViewById(R.id.mv_history_map);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        //为了记录点击的 position，用 position 设置 Tag
        holder.showArea.setTag(position);
        holder.goBack.setTag(position);

        RescueListResData data = datas.get(position);
        holder.no.setText(position + 1 + "");
        holder.callNum.setText("报警编号：" + data.getId());
        holder.fallTime.setText(DateUtil.getStringByFormat(Long.parseLong(data.getC_time()) * 1000, "MM-dd HH:mm"));
        holder.startTime.setText(DateUtil.getStringByFormat(Long.parseLong(data.getTime()) * 1000, "MM-dd HH:mm"));
        holder.callTimes.setText(data.getNum() + "次");
        holder.machineNum.setText(data.getSerial());
        mQuerySn = data.getSerial();
        mShipId = data.getShip();

        int status = Integer.parseInt(data.getStatus());
        switch (status) {
            case 4:
                holder.status.setImageResource(R.drawable.succeed);
                break;
            case 5:
                holder.status.setImageResource(R.drawable.failure);
                break;
            case 6:
                holder.status.setImageResource(R.drawable.user_cancel);
                break;
        }
        if (mCurrentItem == position) {
            mMapView = holder.mMap;
            mBaiduMap = mMapView.getMap();
            mMapView.onResume();
            holder.hideArea.setVisibility(View.VISIBLE);
            holder.goBack.setOnClickListener(innerOnClickListener);
            //mapview中的子类消耗了这个touch事件，所以要改的是该子类
            View v = holder.mMap.getChildAt(0);
            v.setOnTouchListener(innerOnTouchListener);
            //处理之前回到默认值
            ifFirst = true;
            sosLoc.clear();
            actLoc.clear();
            //发送请求获得轨迹
            getSOSOrbit();
            getShipOrbit();
        } else {
            holder.hideArea.setVisibility(View.GONE);
            ifFirst = true;
            sosLoc.clear();
            actLoc.clear();
            mShipId = null;
            mQuerySn = null;
            SOSOrbitGet = false;
            shipOrbitGet = false;
        }
        holder.showArea.setOnClickListener(innerOnClickListener);

        return convertView;
    }

    private void getShipOrbit() {
        if (mShipId != null) {
            model.queryRescueInfoByShip(new AcyncCallBack() {
                @Override
                public void onSuccess(Object obj) {
                    Message msg = new Message();
                    msg.what = GET_SHIP_ORBIT_SUCCESS;
                    msg.obj = obj;
                    mHandler.sendMessage(msg);
                }

                @Override
                public void onFailed() {
                    mHandler.sendEmptyMessage(GET_SHIP_ORBIT_FAILE);
                }
            }, mShipId);
        } else {
            UIUtils.showToast(context, "船只编号为空，查不到救援船只轨迹数据");
        }

    }

    private void getSOSOrbit() {
        model.queryRescueInfoBySn(new AcyncCallBack() {
            @Override
            public void onSuccess(Object obj) {
                Message msg = new Message();
                msg.what = GET_SOS_ORBIT_SUCCESS;
                msg.obj = obj;
                mHandler.sendMessage(msg);
            }

            @Override
            public void onFailed() {
                mHandler.sendEmptyMessage(GET_SOS_ORBIT_FAILE);
            }
        }, mQuerySn);
    }

    private static class ViewHolder {
        private LinearLayout showArea;
        private RelativeLayout hideArea;
        private TextView no;
        private TextView callNum;
        private ImageView status;
        private TextView fallTime;
        private TextView startTime;
        private TextView callTimes;
        private TextView machineNum;
        private ImageButton goBack;
        private TextureMapView mMap;
    }

    private InnerOnClickListener innerOnClickListener = new InnerOnClickListener();

    class InnerOnClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            int tag = (int) v.getTag();
            if (tag == mCurrentItem) {
                mCurrentItem = -1;
            } else {
                mCurrentItem = tag;
            }
            notifyDataSetChanged();
        }
    }

    private CloseOnTouchListener innerOnTouchListener = new CloseOnTouchListener();

    class CloseOnTouchListener implements View.OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                mListView.getRefreshableView().requestDisallowInterceptTouchEvent(false);
            } else {
                mListView.getRefreshableView().requestDisallowInterceptTouchEvent(true);
            }
            return false;
        }
    }

    private void addTargets() {
        mBaiduMap.clear();
        if (actLoc != null && actLoc.size() > 0) {
            double preLat = actLoc.get(0).latitude;
            double preLon = actLoc.get(0).longitude;
            for (int i = 0; i < actLoc.size() - 1; i++) {
                LatLng point = actLoc.get(i);
                LatLng next = actLoc.get(i + 1);
                float direction = MapUtil.getDirection(point, next);
                OverlayOptions options = new MarkerOptions().position(point).icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow_b_up));
                Marker marker = (Marker) mBaiduMap.addOverlay(options);
                //设置marker图标位置
                marker.setAnchor(0.5f, 0.5f);
                marker.setRotate(direction);
                drawLine(preLat, preLon, next.latitude, next.longitude, 0xff004db0);
                preLat = next.latitude;
                preLon = next.longitude;
            }
            LatLng pointLast = actLoc.get(actLoc.size() - 1);
            OverlayOptions options = new MarkerOptions().position(pointLast).icon(BitmapDescriptorFactory.fromResource(R.drawable.origin));
            Marker marker = (Marker) mBaiduMap.addOverlay(options);
            //设置marker图标位置
            marker.setAnchor(0.5f, 0.5f);
            drawLine(preLat, preLon, pointLast.latitude, pointLast.longitude, 0xff004db0);
        }
        if (sosLoc != null && sosLoc.size() > 0) {
            double preTargLat = sosLoc.get(0).latitude;
            double preTargLon = sosLoc.get(0).longitude;
            for (int i = 0; i < sosLoc.size() - 1; i++) {
                LatLng point2 = sosLoc.get(i);
                LatLng next = sosLoc.get(i + 1);
                float direction = MapUtil.getDirection(point2, next);
                OverlayOptions options = new MarkerOptions().position(point2).icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow_r_up));
                Marker marker = (Marker) mBaiduMap.addOverlay(options);
                marker.setAnchor(0.5f, 0.5f);
                marker.setRotate(direction);
                drawLine(preTargLat, preTargLon, next.latitude, next.longitude, 0xaaff0000);
                preTargLat = next.latitude;
                preTargLon = next.longitude;
            }
            LatLng point = sosLoc.get(sosLoc.size() - 1);
            OverlayOptions options = new MarkerOptions().position(point).icon(BitmapDescriptorFactory.fromResource(R.drawable.target));
            Marker marker = (Marker) mBaiduMap.addOverlay(options);
            marker.setAnchor(0.5f, 0.5f);
            drawLine(preTargLat, preTargLon, point.latitude, point.longitude, 0xaaff0000);
        }
    }

    private void drawLine(double preLocLat, double preLocLon, double currentLat, double currentLon, int color) {
        //画连线
        LatLng pre = new LatLng(preLocLat, preLocLon);
        LatLng cur = new LatLng(currentLat, currentLon);
        List<LatLng> points = new ArrayList<>();
        points.add(pre);
        points.add(cur);
        OverlayOptions ooPolyLine = new PolylineOptions().width(10).color(color).points(points);
        mBaiduMap.addOverlay(ooPolyLine);
    }

    private int pageFlage = 1;

    class HistoryBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case Constant.RESCUE_PAUSE:
                    if (mMapView != null && mHandler != null) {
                        mMapView.onPause();
                    }
                    break;
                case Constant.RESCUE_RESUME:

                    if (pageFlage == Constant.FLAG_HISTORY) {
                        if (mMapView != null && mHandler != null) {
                            mMapView.onResume();
                        }
                    }
                    break;
                case Constant.RESCUE_STOP:
                    if (mMapView != null && mHandler != null) {
                        mMapView.onPause();
                    }
                    break;
                case Constant.RESCUE_DESTROY:
                    mMapView.onDestroy();
                    break;
                case Constant.TO_COUNT_PAGE:
                    pageFlage = intent.getIntExtra("flag", 0);
                    if (mMapView != null && mHandler != null) {
                        mMapView.onPause();
                    }
                    break;
                case Constant.TO_HISTORY_PAGE:
                    pageFlage = intent.getIntExtra("flag", 0);
                    if (mMapView != null && mHandler != null) {
                        mMapView.onResume();
                    }
                    break;
                case Constant.TO_RESCUE_PAGE:
                    pageFlage = intent.getIntExtra("flag", 0);
                    if (mMapView != null && mHandler != null) {
                        mMapView.onPause();
                    }
                    break;
            }
        }
    }
}
